<template>
  <el-card>
    <template #header>
      <h1 style="color: #3998a9;">日志管理</h1>
    </template>

    <!-- 查询条件 -->
    <el-form :inline="true" :model="query" style="margin-bottom: 16px;">
      <el-form-item label="时间范围">
        <el-date-picker v-model="query.dateRange" type="datetimerange" range-separator="至" start-placeholder="开始时间"
          end-placeholder="结束时间" format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss" />
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="handleSearch">查询</el-button>
        <el-button @click="resetSearch">重置</el-button>
        <el-button @click="exportLogs">导出</el-button>
      </el-form-item>
    </el-form>

    <!-- 日志表格 -->
    <el-table :data="logs" style="width: 100%" border v-loading="loading">
      <el-table-column prop="createdAt" label="操作时间" width="180">
        <template #default="{ row }">
          {{ formatDateTime(row.createdAt) }}
        </template>
      </el-table-column>
      <el-table-column prop="userId" label="用户ID" width="120">
        <template #default="{ row }">
          <el-tooltip :content="row.userId || '匿名用户'" placement="top">
            <span>{{ truncateText(row.userId || '匿名用户', 20) }}</span>
          </el-tooltip>
        </template>
      </el-table-column>
      <el-table-column prop="action" label="用户操作" width="120">
        <template #default="{ row }">
          <el-tag :type="getTagType(row.action)">{{ row.action || '未知' }}</el-tag>
        </template>
      </el-table-column>
      <el-table-column prop="ipAddress" label="IP地址" width="140" />
      <el-table-column prop="userAgent" label="用户代理" min-width="200">
        <template #default="{ row }">
          <el-tooltip :content="row.userAgent" placement="top">
            <span>{{ truncateText(row.userAgent, 50) }}</span>
          </el-tooltip>
        </template>
      </el-table-column>
    </el-table>

    <!-- 分页 -->
    <div style="margin-top: 20px; text-align: center;">
      <el-pagination v-model:current-page="page" v-model:page-size="pageSize"
        :page-sizes="[10, 20, 50, 100]" layout="total, sizes, prev, pager, next, jumper" :total="total"
        @size-change="handleSizeChange" @current-change="handleCurrentChange" background />
    </div>
  </el-card>
</template>

<script setup>
import { reactive, onMounted, ref } from 'vue'
import { getLogList } from '@/api/log'
import { ElMessage } from 'element-plus'
import * as XLSX from 'xlsx'

// 数据状态
const logs = ref([])
const total = ref(0)
const page = ref(1)
const pageSize = ref(10)
const loading = ref(false)

// 查询条件
const query = reactive({
  dateRange: []
})

// 获取日志数据
const fetchLogs = async () => {
  loading.value = true
  try {
    const params = {
      pageIndex: page.value,
      pageSize: pageSize.value
    }

    // 添加时间范围参数
    if (query.dateRange && query.dateRange.length > 0 && query.dateRange[0]) {
      params.startTime = query.dateRange[0]
    }
    if (query.dateRange && query.dateRange.length > 1 && query.dateRange[1]) {
      params.endTime = query.dateRange[1]
    }

    const response = await getLogList(params)

    if (response && response.code === 200 && response.data) {
      logs.value = response.data.items || []
      total.value = response.data.totalCount || 0
    } else {
      logs.value = []
      total.value = 0
      ElMessage.error('获取日志列表失败')
    }
  } catch (error) {
    ElMessage.error('获取日志列表失败: ' + (error.message || '未知错误'))
  } finally {
    loading.value = false
  }
}

// 搜索处理
const handleSearch = () => {
  page.value = 1
  fetchLogs()
}

// 重置搜索
const resetSearch = () => {
  query.dateRange = []
  page.value = 1
  pageSize.value = 10
  fetchLogs()
}

// 分页处理
const handleSizeChange = (size) => {
  pageSize.value = size
  page.value = 1
  fetchLogs()
}

const handleCurrentChange = (currentPage) => {
  page.value = currentPage
  fetchLogs()
}

// 导出日志
const exportLogs = () => {
  if (logs.value.length === 0) {
    ElMessage.warning('没有数据可导出')
    return
  }

  try {
    // 准备数据
    const headers = ['操作时间', '用户ID', '用户操作', 'IP地址', '用户代理']
    const excelData = logs.value.map(log => [
      formatDateTime(log.createdAt),
      log.userId || '匿名用户',
      log.action || '未知',
      log.ipAddress || '未知',
      log.userAgent || '未知'
    ])

    // 创建工作簿
    const workbook = XLSX.utils.book_new()

    // 创建工作表数据
    const worksheetData = [headers, ...excelData]

    // 创建工作表
    const worksheet = XLSX.utils.aoa_to_sheet(worksheetData)

    // 设置列宽
    const colWidths = [
      { wch: 20 }, // 操作时间
      { wch: 15 }, // 用户ID
      { wch: 15 }, // 用户操作
      { wch: 15 }, // IP地址
      { wch: 50 }  // 用户代理
    ]
    worksheet['!cols'] = colWidths

    // 添加工作表到工作簿
    XLSX.utils.book_append_sheet(workbook, worksheet, '操作日志')

    // 生成Excel文件
    const excelBuffer = XLSX.write(workbook, {
      bookType: 'xlsx',
      type: 'array'
    })

    // 创建Blob并下载
    const blob = new Blob([excelBuffer], {
      type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
    })
    const url = URL.createObjectURL(blob)
    const a = document.createElement('a')
    a.href = url
    a.download = `操作日志_${new Date().toISOString().slice(0, 10)}.xlsx`
    a.click()
    URL.revokeObjectURL(url)

    ElMessage.success('导出成功')
  } catch (error) {
    ElMessage.error('导出失败，请检查xlsx依赖是否正确安装')
  }
}

// 格式化日期时间
const formatDateTime = (dateTime) => {
  if (!dateTime) return '未知'
  return new Date(dateTime).toLocaleString('zh-CN')
}

// 获取标签类型
const getTagType = (action) => {
  if (!action) return 'info'

  const actionMap = {
    '登录': 'success',
    '登出': 'warning',
    '新增': 'primary',
    '编辑': 'primary',
    '删除': 'danger',
    '查询': 'info',
    '导出': 'success',
    '导入': 'success'
  }

  for (const [key, type] of Object.entries(actionMap)) {
    if (action.includes(key)) {
      return type
    }
  }

  return 'info'
}

// 截断文本
const truncateText = (text, maxLength) => {
  if (!text) return '未知'
  return text.length > maxLength ? text.substring(0, maxLength) + '...' : text
}

// 初始化
onMounted(() => {
  fetchLogs()
})
</script>

<style scoped>
.log-query-form {
  margin-bottom: 16px;
}
</style>